from typing import Any, Dict
from fastapi import APIRouter, HTTPException, BackgroundTasks

from .dto.flow_create import FlowCreate
from .dto.flow_id import FlowId
from .dto.flow_update_in import FlowUpdateIn
from .dto.run_flow_request import RunFlowRequest
from .dto.mermaid_request import MermaidRequest
# 控制器不直接依赖具体执行引擎，统一走服务层，降低耦合
from ..utils import envelope
from ..services.flows_service import (
    create_flow_service,
    list_flows_service,
    get_flow_service,
    update_flow_service,
    delete_flow_service,
    validate_flow_service,
    mermaid_service,
    run_flow_service,
    run_demo_service,
)

router = APIRouter(prefix="/flows", tags=["flows"])


@router.post("/")
def api_create_flow(payload: FlowCreate):
    try:
        flow_id = create_flow_service(payload)
        return envelope({"id": flow_id})
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/list")
def api_list_flows():
    items = list_flows_service()
    return envelope(items)


@router.post("/get")
def api_get_flow(payload: FlowId):
    f = get_flow_service(payload.flow_id)
    if not f:
        raise HTTPException(status_code=404, detail="Flow not found")
    return envelope({"item": f})


@router.post("/update")
def api_update_flow(payload: FlowUpdateIn):
    ok = update_flow_service(payload)
    if not ok:
        raise HTTPException(status_code=404, detail="Flow not found or no changes")
    return envelope({"updated": True})


@router.post("/delete")
def api_delete_flow(payload: FlowId):
    ok = delete_flow_service(payload.flow_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Flow not found")
    return envelope({"deleted": True})


@router.post("/run")
def api_run_flow(payload: RunFlowRequest, bg: BackgroundTasks):
    try:
        run_id, task = run_flow_service(payload.flow_id, payload.params)
        bg.add_task(task)
        return envelope({"run_id": run_id, "status": "pending"})
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/run_demo")
def api_run_flow_demo(payload: FlowId, bg: BackgroundTasks):
    try:
        run_id, task = run_demo_service(payload.flow_id)
        bg.add_task(task)
        return envelope({"run_id": run_id, "status": "pending"})
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/validate")
def api_validate_flow(payload: FlowId):
    try:
        ok = validate_flow_service(payload.flow_id)
        return envelope({"valid": ok})
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/mermaid")
def api_generate_mermaid(payload: MermaidRequest):
    code = mermaid_service(payload.flow.model_dump())
    return envelope({"mermaid": code})